【算法】约瑟夫环问题(报数出列)

  • 题目描述
    已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
  • 输入
    7 3
  • 输出
    3 6 2 7 5 1 4

  • 算法思路
    先假设,编号是0~n-1,报数是从0~m-1,因为只要在最后结果+1,就变回编号1~n了。
    第i=1次报数:A)0 1 2 3 4 5 6,n=7,淘汰2,于是变为0 1 3 4 5 6 ,
    接下来报数顺序为:B)3 4 5 6 0 1,n=6
    第i=2次报数:C)0 1 2 3 4 5,C变回B,只要(C+m)%n即可,
    淘汰2,于是变为0 1 3 4 5,接下来报数顺序为:D)3 4 5 0 1,n=5
    第i=3次报数:E)0 1 2 3 4,E变回D,只要(E+m)%n即可
    以此类推。。。。
    我们可以知道:
    第i次淘汰的数可以归纳出下面的递归公式:
    f(n,m,i)=[f(n-1,m,i)+m]%n;
    当i=1时,f(n,m,1)=(n+m-1)%n;

  • 算法如下
public class LastRemaining {
    public int LastRem(int n, int m,int i) {
        if(i==1)
           return (n+m-1)%n;
        else
           return (LastRem(n-1,m,i-1)+m)%n;
    }
    public static void main(String[] args) {
        LastRemaining cls = new LastRemaining();
        for(int i=1;i<=7;i++)
          System.out.println(cls.LastRem(7, 3,i)+1);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值